/**
 * Android FriendFeed Client
 * Copyright (C) 2010 E & B Labs
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package net.eblabs.json;

import android.util.Log;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.URISyntaxException;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthSchemeRegistry;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.impl.auth.BasicScheme;
import org.apache.http.impl.auth.BasicSchemeFactory;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.HttpConnectionParams;
import org.json.JSONException;
import org.json.JSONObject;

/**
 * Cliente JSon.
 * @author Raul Romero (raul@bgta.net)
 */
public class JsonClient {

    private static final int CONNECTION_TIMEOUT_MS = 30 * 1000;
    private static final int SOCKET_TIMEOUT_MS = 30 * 1000;
    public static final int RETRIEVE_LIMIT = 50;
    private DefaultHttpClient httpClient;
    private AuthScope authScope;
    private String username;
    private String password;

    public JsonClient(String host) {
        this.prepareHttpClient(host);
    }

    private void prepareHttpClient(String hostname) {
        this.authScope = new AuthScope(hostname, AuthScope.ANY_PORT);
        this.httpClient = new DefaultHttpClient();

        BasicScheme basicScheme = new BasicScheme();
        AuthSchemeRegistry authRegistry = new AuthSchemeRegistry();
        authRegistry.register(basicScheme.getSchemeName(),
                new BasicSchemeFactory());

        this.httpClient.setAuthSchemes(authRegistry);
        this.httpClient.setCredentialsProvider(new BasicCredentialsProvider());
    }

    public void setCredentials(String username, String password) {
        this.username = username;
        this.password = password;
        this.httpClient.getCredentialsProvider().setCredentials(this.authScope,
                new UsernamePasswordCredentials(username, password));
    }

    /**
     * Convierte un Stream a String.
     * @param is InputStream a convertir
     * @return String con el contenido del InputStream
     * @throws IOException en caso de error.
     */
    public static String stringifyStream(InputStream is) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        StringBuilder sb = new StringBuilder();
        String line;

        while ((line = reader.readLine()) != null) {
            sb.append(line + "\n");
        }
       
        return sb.toString();
    }
    protected JSONObject getJSONObject(HttpUriRequest httpRequest)
            throws URISyntaxException,
            UnsupportedEncodingException,
            IOException, 
            JSONException {
        
        HttpResponse response = this.getResponse(httpRequest);

        InputStream data = response.getEntity().getContent();

        JSONObject json = null;

        json = new JSONObject(stringifyStream(data));
        
        data.close();

        return json;
    }

    protected HttpResponse getResponse(HttpUriRequest httpRequest)
            throws URISyntaxException,
            UnsupportedEncodingException,
            IOException {

        if (httpRequest instanceof HttpPost) {
            HttpPost post = (HttpPost) httpRequest;
            // See this:
            // http://groups.google.com/group/twitter-development-talk/browse_thread/thread/e178b1d3d63d8e3b
            post.getParams().setBooleanParameter("http.protocol."
                    + "expect-continue", false);
        }

        HttpConnectionParams.setConnectionTimeout(httpRequest.getParams(),
                CONNECTION_TIMEOUT_MS);
        HttpConnectionParams.setSoTimeout(httpRequest.getParams(),
                SOCKET_TIMEOUT_MS);

        HttpResponse response;


        return this.httpClient.execute(httpRequest);
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.setCredentials(this.getUsername(), password);
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.setCredentials(username, this.getPassword());
    }
}
